home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / KEY-FAKE.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  7KB  |  247 lines

  1. ;    KEY-FAKE.ASM -- Fakes keystrokes from internal keyboard buffer.
  2. ;    ============
  3.  
  4. CSEG        Segment 
  5.         Assume    CS:CSEG
  6.         Org    0100h
  7. Entry:        Jmp    Initialize
  8.  
  9. ;    Most Resident Data
  10. ;    ------------------
  11.  
  12.         db    'KEY-FAKE (C) Copyright Charles Petzold, 1985'
  13. SearchLabelEnd    Label    Byte 
  14.  
  15. OldInterrupt16    dd    0
  16. Pointer        dw    Offset KeyStrokeBuffer
  17. Counter        db    0
  18.  
  19. ;    New Interrupt 16 (Keyboard)
  20. ;    ---------------------------
  21.  
  22. NewInterrupt16    Proc    Far
  23.  
  24.         Sti            ; Allow futher interrupts    
  25.         Cmp    CS:[Counter],0    ; See if characters in buffer
  26.         Jz    DoOldInterrupt    ; If not, just do regular interrupt
  27.  
  28.         Or    AH,AH        ; Check if AH is zero
  29.         Jz    GetCharacter    ; If so, call is to get character
  30.  
  31.         Cmp    AH,1        ; Check if AH is one
  32.         Jz    GetStatus    ; If so, call is for status 
  33.  
  34. DoOldInterrupt:    Jmp    CS:[OldInterrupt16]    ; Otherwise, go away
  35.  
  36. GetCharacter:    Push    BX
  37.         Mov    BX,CS:[Pointer]    ; BX points to current buffer position
  38.         Mov    AX,CS:[BX]    ; Get ASCII code and scan code
  39.         Inc    BX        ; Move buffer pointer ahead
  40.         Inc    BX
  41.         Mov    CS:[Pointer],BX    ; Save new pointer
  42.         Dec    CS:[Counter]    ; One less character in counter
  43.         Pop    BX
  44.  
  45.         Or    AX,AX        ; See if 0 returned
  46.         Jz    NewInterrupt16    ; If so, take it from the top again
  47.         
  48.         IRet            ; Return to calling program
  49.  
  50. GetStatus:    Push    BX
  51.         Mov    BX,CS:[Pointer]    ; BX points to current buffer position
  52.         Mov    AX,CS:[BX]    ; Get ASCII code and scan code
  53.         Pop    BX
  54.  
  55.         Or    AX,AX        ; See if special 0 keystroke
  56.         Jnz    StatusReturn    ; If not, return non-zero flag
  57.  
  58.         Add    CS:[Pointer],2    ; If so, skip over it
  59.         Dec    CS:[Counter]    ; One less character
  60.         Or    AX,AX        ; Will set zero flag
  61.  
  62. StatusReturn:    Ret    2        ; Do not pop flags
  63.  
  64. NewInterrupt16    EndP
  65.  
  66. ;    Beginning of Key Stroke Buffer
  67. ;    ------------------------------
  68.  
  69. KeyStrokeBuffer    Label    Byte        ; 256 Byte Buffer for keystrokes
  70.  
  71. ;    Initialization -- Search through Memory and see if label matches
  72. ;    ----------------------------------------------------------------
  73. ;
  74. ;        If so, use the loaded program; if not, create a new interrupt
  75.  
  76.         Assume    DS:CSEG, ES:CSEG, SS:CSEG
  77.  
  78. Initialize:    Mov    Word Ptr [Entry],0    ; Slightly modify search label
  79.         Mov    Byte Ptr [Entry + 2],0    ;   so no false matches
  80.  
  81.         Cld
  82.         Mov    DX,CS            ; This segment
  83.         Sub    AX,AX            ; Beginning of search
  84.         Mov    ES,AX            ; Search segment
  85.  
  86. SearchLoop:    Mov    SI,100h            ; Address to search
  87.         Mov    DI,SI            ; Set pointers to same address
  88.         Mov    CX,Offset SearchLabelEnd - Offset Entry
  89.         Repz    Cmpsb            ; Check for match
  90.         Jz    ReadyForDecode        ; If label matches
  91.  
  92.         Inc    AX            ; Still the search segment 
  93.         Mov    ES,AX            ; ES to next segment
  94.  
  95.         Cmp    AX,DX            ; Check if it's this segment
  96.         Jnz    SearchLoop        ; Try another compare
  97.  
  98.         Mov    Byte Ptr DS:[1],27h    ; Since no match found,
  99.                         ;   set up PSP for Terminate &
  100.                         ;   remain resident.
  101.  
  102. ;    Save and Set Interupt 16 if Staying Resident
  103. ;    --------------------------------------------
  104.  
  105.         Sub    AX,AX            ; Set AX to zero
  106.         Mov    DS,AX            ; To access vector segment
  107.         Assume    DS:Nothing        ; Tell the assembler
  108.  
  109.         Mov    AX,Word Ptr DS:[16h * 4]    ; Get vector offset
  110.         Mov    Word Ptr CS:[OldInterrupt16],AX    ; Save it
  111.         Mov    AX,Word Ptr DS:[16h * 4 + 2]    ; Get vector segment
  112.         Mov    Word Ptr CS:[OldInterrupt16 + 2],AX    ; and save it
  113.  
  114.         Cli                    ; Don't interrupt me
  115.         Mov    DS:[16h * 4],Offset NewInterrupt16    ; Store new
  116.         Mov    DS:[16h * 4 + 2],CS        ; address
  117.         Sti                    ; Now you can talk
  118.  
  119.         Push    CS
  120.         Pop    DS                ; Restore DS
  121.         Assume    DS:CSEG
  122.  
  123. ;    Parameter decoding when program segment has been found
  124. ;    ------------------------------------------------------
  125. ;
  126. ;        ES = segment of loaded program (could be CS)
  127.  
  128. ReadyForDecode:    Mov    SI,80h        ; SI points to parameter area
  129.         Mov    DI,Offset KeyStrokeBuffer
  130.         Mov    ES:[Pointer],DI    ; ES:DI points to buffer area
  131.         Mov    ES:[Counter],0    ; Set keystroke counter to zero
  132.  
  133.         Lodsb            ; Get parameter count
  134.         Cbw            ; Convert to word
  135.         Mov    CX,AX        ; CX = parameter count
  136.         Inc    CX        ; So catch last delimiter (0D)
  137.         Or    AX,AX        ; Check if parameter present
  138.         Jnz    GoDecodeLoop    ; If so, continue
  139.         Jmp    EndDecode    ; If not, cut out
  140.  
  141. GoDecodeLoop:    Jmp    DecodeLoop
  142.  
  143. ;    End of Residence is end of Key Stroke Buffer
  144. ;    --------------------------------------------
  145.  
  146.         Org    256 + Offset KeyStrokeBuffer
  147.  
  148. EndResidence    Label    Byte
  149.  
  150. ;    Data for Parameter Decoding
  151. ;    ---------------------------
  152.  
  153. QuoteSign    db    0        ; Flag for quoted strings
  154. DoingNumber    db    0        ; Flag for doing a number    
  155. DoingExtended    db    0        ; Flag for doing extended ASCII    
  156. CalcNumber    db    0        ; A calculated number 
  157. Ten        db    10        ; For MUL convenience 
  158.  
  159. ;    Routine for doing quoted text
  160. ;    -----------------------------
  161.         
  162. DecodeLoop:    Lodsb            ; Get character
  163.         Cmp    [QuoteSign],0    ; Check if doing quoted text
  164.         Jz    NotDoingQuote    ; If not, continue checks
  165.  
  166.         Cmp    AL,[QuoteSign]    ; Check first if character is quote
  167.         Jz    EndQuote    ; If so, finish quoted text
  168.  
  169.         Sub    AH,AH        ; Set scan code to zero
  170.         Stosw            ; Save it in buffer
  171.         Inc    ES:[Counter]    ; One more character
  172.         Jmp    DoNextCharacter    ; Go to bottom of routine
  173.  
  174. EndQuote:    Mov    [QuoteSign],0    ; End of quoted text
  175.         Jmp    DoNextCharacter    ; Get the next character
  176.  
  177. ;    Routine for Extended Ascii Character (@)
  178. ;    ----------------------------------------
  179.  
  180. NotDoingQuote:    Cmp    AL,'@'        ; See if character is for extended
  181.         Jnz    NotExtended    ; If not, hop over a little code
  182.  
  183.         Mov    [DoingExtended],1    ; Flag for extended ASCII 
  184.         Jmp    Delimiter        ; To possibly dump number
  185.  
  186. ;    Routine for Quote Sign ' or "
  187. ;    -----------------------------
  188.  
  189. NotExtended:    Cmp    AL,'"'        ; Check for a double quote sign
  190.         Jz    Quote    
  191.         Cmp    AL,"'"        ; Check for a single quote sign
  192.         Jnz    NotAQuote
  193.  
  194. Quote:        Mov    [QuoteSign],AL    ; Save the quote sign
  195.         Jmp    Delimiter    ; To possibly dump number
  196.  
  197. ;    Routine for decimal number
  198. ;    --------------------------
  199.  
  200. NotAQuote:    Cmp    AL,'0'        ; See if character >= 0
  201.         Jb    Delimiter
  202.         Cmp    AL,'9'        ; See if character <= 9
  203.         Ja    Delimiter
  204.  
  205.         Mov    [DoingNumber],1        ; If so, doing number
  206.  
  207.         Sub    AL,'0'            ; Convert to binary
  208.         Xchg    AL,[CalcNumber]        ; Get previously calculated
  209.         Mul    [Ten]            ; Multiply by 10
  210.         Add    [CalcNumber],AL        ; Add it to new digit
  211.  
  212.         Jmp    DoNextCharacter        ; And continue
  213.  
  214. ;    Anything else is considered a delimiter
  215. ;    ---------------------------------------
  216.  
  217. Delimiter:    Cmp    [DoingNumber],1        ; Check if doing a number
  218.         Jnz    DoNextCharacter        ; If not, do not dump
  219.  
  220.         Mov    AL,[CalcNumber]        ; Set AX to ASCII number
  221.         Sub    AH,AH            ; Zero out scan code part
  222.         Cmp    [DoingExtended],1    ; Check if doing scan code
  223.         Jnz    NumberOK
  224.  
  225.         Xchg    AL,AH            ; Switch ASCII and scan code
  226.         
  227. NumberOK:    Stosw                ; Store the two codes
  228.         Inc    ES:[Counter]        ; One more character in buffer
  229.  
  230.         Mov    [DoingNumber],0        ; Clear out all flags
  231.         Mov    [DoingExtended],0
  232.         Mov    [CalcNumber],0
  233.  
  234. DoNextCharacter:Dec    CX            ; One less character to do
  235.         Jz    EndDecode        ; If no more, we're done
  236.         Jmp    DecodeLoop        ; Otherwise, get next one
  237.  
  238. ;    End Decode -- Ready to terminate (and possibly stay resident)
  239. ;    -------------------------------------------------------------
  240.  
  241. EndDecode:    Mov    DX,Offset EndResidence    ; End of resident part
  242.         Ret                ; Int 20h or 27h
  243.  
  244. CSEG        EndS
  245.  
  246.         End Entry
  247.